package com.yanqu.road.server.timer.union.cross;

import com.yanqu.road.entity.player.UserHistoryAttribute;
import com.yanqu.road.logic.bussiness.player.UserHistoryAttributeBussiness;
import com.yanqu.road.pb.union.cross.CrossUnionProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.PlayerModule;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.executor.GeneralTask;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 定时器：检查和同步玩家历史最高赚钱到商会跨服，要等CrossUnionMgr的isAllSync=true后
 */
public class CrossUnionMemberAbilitySyncTask extends GeneralTask {
    private static Logger logger = LogManager.getLogger(CrossUnionMemberAbilitySyncTask.class);
    private static boolean running = false;
    private static LinkedList<Long> waitUpdateAbilityUsers = new LinkedList<>();
    @Override
    public void doRun() {
        if (!running) {
            running = true;
            try {
                if (!CrossUnionMgr.isAllSync()) {
                    return;
                }
                // 20秒一次
                long param = 20;
                long secondIndex = System.currentTimeMillis() / 1000 % param;
                long canSendIndex = GameServer.getInstance().getServerId() % param;
                if (secondIndex != canSendIndex) {
                    return;
                }

                List<Long> updateAbilityUsers = popWaitUpdateAbilityUsers();
                if (!updateAbilityUsers.isEmpty()) {
                    CrossUnionProto.CrossUnionUpdateHistoryMaxAbilityReq.Builder syncMsg = CrossUnionProto.CrossUnionUpdateHistoryMaxAbilityReq.newBuilder();
                    for (Long userId : updateAbilityUsers) {
                        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                        BigInteger ability = BigInteger.ZERO;
                        if (null != player) {
                            UserHistoryAttribute userHistoryAttribute = player.getModule(PlayerModule.class).getUserHistoryAttribute();
                            ability = userHistoryAttribute.getAbility();
                        } else {
                            UserHistoryAttribute userHistoryAttribute = UserHistoryAttributeBussiness.getUserHistoryAttribute(userId);
                            if(null == userHistoryAttribute) {
                                continue;
                            }
                            ability = userHistoryAttribute.getAbility();
                        }
                        CrossUnionProto.MemberHistoryMaxAbilityTemp.Builder abilityMsg = CrossUnionProto.MemberHistoryMaxAbilityTemp.newBuilder();
                        abilityMsg.setUserId(userId);
                        abilityMsg.setAbility(ability.toString());
                        syncMsg.addMemberAbilityList(abilityMsg);
                    }
                    GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(Protocol.C_UNION_UPDATE_MEMBER_MAX_ABILITY, syncMsg));
                }



            } catch (Exception e) {
                logger.error("MemberAbilitySync error. ", e);
            } finally {
                running = false;
            }
        }
    }

    private List<Long> popWaitUpdateAbilityUsers() {
        List<Long> userIds = new ArrayList<>();
        int takeCount = 300;
        synchronized (waitUpdateAbilityUsers) {
            while (!waitUpdateAbilityUsers.isEmpty()) {
                Long userId = waitUpdateAbilityUsers.pop();
                userIds.add(userId);
                if (--takeCount <= 0) {
                    break;
                }
            }
        }
        return userIds;
    }

    public static void addWaitUpdateAbilityUser(long userId) {
        synchronized (waitUpdateAbilityUsers) {
            if (!waitUpdateAbilityUsers.contains(userId)) {
                waitUpdateAbilityUsers.addLast(userId);
            }
        }
    }

    public static void addWaitUpdateAbilityUser(List<Long> userIds) {
        if (null == userIds || userIds.isEmpty()) {
            return;
        }
        synchronized (waitUpdateAbilityUsers) {
            for (Long userId : userIds) {
                if (!waitUpdateAbilityUsers.contains(userId)) {
                    waitUpdateAbilityUsers.addLast(userId);
                }
            }
        }
    }
}
